//SPDX-FileCopyrightText: Copyright 2022-2024 深圳市同心圆网络有限公司
//SPDX-License-Identifier: GPL-3.0-only

import React, { useEffect, useState } from "react";
import type { UserDataSourceInfo, SourceInfoType, GitSourceInfo, TenCloudSourceInfo, SOURCE_TYPE } from "@/api/user_dataview";
import { SOURCE_TYPE_ATOMGIT, SOURCE_TYPE_GITCODE, SOURCE_TYPE_GITEE, SOURCE_TYPE_GITLAB, SOURCE_TYPE_TEN_COLOUD, add_source, update_source } from "@/api/user_dataview";
import { Checkbox, Form, Input, message, Modal, Popover, Select, Space } from "antd";
import { InfoCircleOutlined } from "@ant-design/icons";
import { open as shell_open } from '@tauri-apps/api/shell';
import { get_self_info as get_atomgit_self_info } from "@/api/atomgit/user";
import { get_self_info as get_gitcode_self_info } from "@/api/gitcode/user";
import { get_self_info as get_gitee_self_info } from "@/api/gitee/user";
import { get_self_info as get_gitlab_self_info } from "@/api/gitlab/user";
import { getAccountSummary } from "@/api/tencloud/cam";

import { uniqId } from "@/utils/utils";
import { useStores } from "@/hooks";

export interface EditLocalSourceModalProps {
    sourceInfo?: UserDataSourceInfo;
    onCancel: () => void;
    onOk: () => void;
}

const EditLocalSourceModal = (props: EditLocalSourceModalProps) => {
    const appStore = useStores('appStore');

    const [name, setName] = useState(props.sourceInfo?.name ?? "");
    const [sourceType, setSourceType] = useState(props.sourceInfo?.source_type ?? SOURCE_TYPE_ATOMGIT);
    const [innerInfo, setInnerInfo] = useState<SourceInfoType | null>(null);

    const testSource = async () => {
        if (innerInfo == null) {
            return false;
        }
        if (sourceType == SOURCE_TYPE_ATOMGIT) {
            try {
                await get_atomgit_self_info((innerInfo as GitSourceInfo).accessToken);
                return true;
            } catch (e) {
                console.log(e);
                return false;
            }
        } else if (sourceType == SOURCE_TYPE_GITCODE) {
            try {
                await get_gitcode_self_info((innerInfo as GitSourceInfo).accessToken);
                return true;
            } catch (e) {
                console.log(e);
                return false;
            }
        } else if (sourceType == SOURCE_TYPE_GITEE) {
            try {
                await get_gitee_self_info((innerInfo as GitSourceInfo).accessToken);
                return true;
            } catch (e) {
                console.log(e);
                return false;
            }
        } else if (sourceType == SOURCE_TYPE_GITLAB) {
            try {
                const sourceInfo = innerInfo as GitSourceInfo;
                const url = new URL(sourceInfo.baseUrl ?? "");
                await get_gitlab_self_info(`${url.protocol}//${url.host}`, sourceInfo.accessToken);
                return true;
            } catch (e) {
                console.log(e);
                return false;
            }
        } else if (sourceType == SOURCE_TYPE_TEN_COLOUD) {
            try {
                const sourceInfo = innerInfo as TenCloudSourceInfo;
                await getAccountSummary(sourceInfo.secretId, sourceInfo.secretKey);
                return true;
            } catch (e) {
                console.log(e);
                return false;
            }
        }
        return true;
    };

    const addSource = async () => {
        let ok = await testSource();
        if (!ok) {
            message.error("无法连接数据源");
            return;
        }
        message.info("连接数据源成功");
        await add_source({
            id: uniqId(),
            name: name,
            source_type: sourceType,
            source_info: JSON.stringify(innerInfo),
        });
        message.info("增加成功");
        props.onOk();
    };

    const updateSource = async () => {
        let ok = await testSource();
        if (!ok) {
            message.error("无法连接数据源");
            return;
        }
        message.info("连接数据源成功");
        await update_source({
            id: props.sourceInfo?.id ?? "",
            name: name,
            source_type: sourceType,
            source_info: JSON.stringify(innerInfo),
        });
        message.info("修改成功");
        props.onOk();
    };

    const checkValid = () => {
        if (innerInfo == null) {
            return false;
        }
        if ([SOURCE_TYPE_ATOMGIT, SOURCE_TYPE_GITCODE, SOURCE_TYPE_GITEE].includes(sourceType)) {
            if ((innerInfo as GitSourceInfo).accessToken == "") {
                return false;
            }
        }
        if (sourceType == SOURCE_TYPE_GITLAB) {
            if (((innerInfo as GitSourceInfo).baseUrl ?? "") == "") {
                return false;
            }
        }
        if (sourceType == SOURCE_TYPE_TEN_COLOUD) {
            if ((innerInfo as TenCloudSourceInfo).secretId == "") {
                return false;
            }
            if ((innerInfo as TenCloudSourceInfo).secretKey == "") {
                return false;
            }
            if ((innerInfo as TenCloudSourceInfo).regionList.length == 0) {
                return false;
            }
        }
        return true;
    };

    const adjustSourceType = async (newType: SOURCE_TYPE) => {
        if ([SOURCE_TYPE_ATOMGIT, SOURCE_TYPE_GITCODE, SOURCE_TYPE_GITEE].includes(newType)) {
            const tmpInfo: GitSourceInfo = {
                accessToken: "",
            }
            setInnerInfo(tmpInfo);
        } else if (newType == SOURCE_TYPE_GITLAB) {
            const tmpInfo: GitSourceInfo = {
                accessToken: "",
                baseUrl: "",
            }
            setInnerInfo(tmpInfo);
        } else if (newType == SOURCE_TYPE_TEN_COLOUD) {
            const tmpInfo: TenCloudSourceInfo = {
                secretId: "",
                secretKey: "",
                regionList: [],
                enableLightHouse: true,
                enableDns: true,
                enableCdn: true,
            }
            setInnerInfo(tmpInfo);
        }
        setSourceType(newType);
    };

    useEffect(() => {
        if (props.sourceInfo !== undefined) {
            setInnerInfo(JSON.parse(props.sourceInfo.source_info));
        }
    }, [props.sourceInfo]);

    useEffect(() => {
        if (props.sourceInfo !== undefined) {
            return;
        }
        if (appStore.vendorCfg != null) {
            if (appStore.vendorCfg.dataview.enable_atomgit) {
                adjustSourceType(SOURCE_TYPE_ATOMGIT);
            } else if (appStore.vendorCfg.dataview.enable_gitcode) {
                adjustSourceType(SOURCE_TYPE_GITCODE);
            } else if (appStore.vendorCfg.dataview.enable_gitee) {
                adjustSourceType(SOURCE_TYPE_GITEE);
            } else if (appStore.vendorCfg.dataview.enable_gitlab) {
                adjustSourceType(SOURCE_TYPE_GITLAB);
            } else if (appStore.vendorCfg.dataview.enable_tencloud) {
                adjustSourceType(SOURCE_TYPE_TEN_COLOUD);
            }
        }
    }, [props.sourceInfo, appStore.vendorCfg]);

    return (
        <Modal open title={`${props.sourceInfo == undefined ? "增加" : "修改"}数据源`} mask={false}
            okText={props.sourceInfo == undefined ? "增加" : "修改"} okButtonProps={{ disabled: !checkValid() }}
            bodyStyle={{ maxHeight: "calc(100vh - 300px)", overflowY: "scroll" }}
            onCancel={e => {
                e.stopPropagation();
                e.preventDefault();
                props.onCancel();
            }}
            onOk={e => {
                e.stopPropagation();
                e.preventDefault();
                if (props.sourceInfo == undefined) {
                    addSource();
                } else {
                    updateSource();
                }
            }}>
            <Form labelCol={{ span: 6 }}>
                <Form.Item label="提示">
                    所有信息保存在本地机器，不上传服务器。
                </Form.Item>
                <Form.Item label="名称">
                    <Input value={name} onChange={e => {
                        e.stopPropagation();
                        e.preventDefault();
                        setName(e.target.value.trim());
                    }} status={name == "" ? "error" : undefined} />
                </Form.Item>
                <Form.Item label="类型" help={
                    <>
                        {sourceType == SOURCE_TYPE_TEN_COLOUD && "需要赋予ReadOnlyAccess权限"}
                    </>
                }>
                    <Select value={sourceType} onChange={value => adjustSourceType(value)} disabled={props.sourceInfo != undefined}>
                        {(appStore.vendorCfg?.dataview.enable_atomgit || props.sourceInfo != undefined) && (
                            <Select.Option value={SOURCE_TYPE_ATOMGIT}>AtomGit</Select.Option>
                        )}
                        {(appStore.vendorCfg?.dataview.enable_gitcode || props.sourceInfo != undefined) && (
                            <Select.Option value={SOURCE_TYPE_GITCODE}>GitCode</Select.Option>
                        )}
                        {(appStore.vendorCfg?.dataview.enable_gitee || props.sourceInfo != undefined) && (
                            <Select.Option value={SOURCE_TYPE_GITEE}>Gitee</Select.Option>
                        )}
                        {(appStore.vendorCfg?.dataview.enable_gitlab || props.sourceInfo != undefined) && (
                            <Select.Option value={SOURCE_TYPE_GITLAB}>GitLab</Select.Option>
                        )}
                        {(appStore.vendorCfg?.dataview.enable_tencloud || props.sourceInfo != undefined) && (
                            <Select.Option value={SOURCE_TYPE_TEN_COLOUD}>腾讯云</Select.Option>
                        )}
                    </Select>
                </Form.Item>
                {innerInfo != null && (
                    <>
                        {sourceType == SOURCE_TYPE_GITLAB && (
                            <Form.Item label="访问地址" help="必须以http://或者https://开头">
                                <Input value={(innerInfo as GitSourceInfo).baseUrl ?? ""} onChange={e => {
                                    e.stopPropagation();
                                    e.preventDefault();
                                    setInnerInfo({
                                        ...innerInfo,
                                        baseUrl: e.target.value.trim(),
                                    });
                                }} status={(((innerInfo as GitSourceInfo).baseUrl ?? "").startsWith("http://") || ((innerInfo as GitSourceInfo).baseUrl ?? "").startsWith("https://")) ? undefined : "error"} />
                            </Form.Item>
                        )}
                        {[SOURCE_TYPE_ATOMGIT, SOURCE_TYPE_GITCODE, SOURCE_TYPE_GITEE, SOURCE_TYPE_GITLAB].includes(sourceType) && (
                            <Form.Item label="访问密钥" help={
                                <>
                                    {sourceType == SOURCE_TYPE_ATOMGIT && (
                                        <Space>
                                            <a onClick={e => {
                                                e.stopPropagation();
                                                e.preventDefault();
                                                shell_open("https://atomgit.com/-/profile/tokens");
                                            }}>创建令牌</a>
                                            <Popover trigger="hover" placement="right" title="提示" content="需要打开repo,read:repo_issues,read:org,read:user权限">
                                                <InfoCircleOutlined />
                                            </Popover>
                                        </Space>
                                    )}
                                    {sourceType == SOURCE_TYPE_GITCODE && (
                                        <Space>
                                            <a onClick={e => {
                                                e.stopPropagation();
                                                e.preventDefault();
                                                shell_open("https://gitcode.com/setting/token-classic");
                                            }}>创建令牌</a>
                                            <Popover trigger="hover" placement="right" title="提示" content="所有权限都设置为只读">
                                                <InfoCircleOutlined />
                                            </Popover>
                                        </Space>
                                    )}
                                    {sourceType == SOURCE_TYPE_GITEE && (
                                        <Space>
                                            <a onClick={e => {
                                                e.stopPropagation();
                                                e.preventDefault();
                                                shell_open("https://gitee.com/profile/personal_access_tokens");
                                            }}>创建令牌</a>
                                            <Popover trigger="hover" placement="right" title="提示" content="使用默认权限配置即可">
                                                <InfoCircleOutlined />
                                            </Popover>
                                        </Space>
                                    )}
                                </>
                            }>
                                <Input.Password value={(innerInfo as GitSourceInfo).accessToken} onChange={e => {
                                    e.stopPropagation();
                                    e.preventDefault();
                                    setInnerInfo({
                                        ...innerInfo,
                                        accessToken: e.target.value.trim(),
                                    });
                                }} status={(innerInfo as GitSourceInfo).accessToken == "" ? "error" : undefined} />
                            </Form.Item>
                        )}

                        {sourceType == SOURCE_TYPE_TEN_COLOUD && (
                            <>
                                <Form.Item label="密钥ID">
                                    <Input value={(innerInfo as TenCloudSourceInfo).secretId} onChange={e => {
                                        e.stopPropagation();
                                        e.preventDefault();
                                        setInnerInfo({
                                            ...innerInfo,
                                            secretId: e.target.value.trim(),
                                        });
                                    }} />
                                </Form.Item>
                                <Form.Item label="密钥">
                                    <Input.Password value={(innerInfo as TenCloudSourceInfo).secretKey} onChange={e => {
                                        e.stopPropagation();
                                        e.preventDefault();
                                        setInnerInfo({
                                            ...innerInfo,
                                            secretKey: e.target.value.trim(),
                                        });
                                    }} />
                                </Form.Item>
                                <Form.Item label="地域">
                                    <Select mode="multiple" value={(innerInfo as TenCloudSourceInfo).regionList} onChange={values => setInnerInfo({
                                        ...innerInfo,
                                        regionList: values,
                                    })}>
                                        <Select.Option value="ap-bangkok">亚太东南（曼谷）</Select.Option>
                                        <Select.Option value="ap-beijing">华北地区（北京）</Select.Option>
                                        <Select.Option value="ap-chengdu">西南地区（成都）</Select.Option>
                                        <Select.Option value="ap-guangzhou">华南地区（广州）</Select.Option>
                                        <Select.Option value="ap-hongkong">港澳台地区（中国香港）</Select.Option>
                                        <Select.Option value="ap-jakarta">亚太东南（雅加达）</Select.Option>
                                        <Select.Option value="ap-mumbai">亚太南部（孟买）</Select.Option>
                                        <Select.Option value="ap-nanjing">华东地区（南京）</Select.Option>
                                        <Select.Option value="ap-seoul">亚太东北（首尔）</Select.Option>
                                        <Select.Option value="ap-shanghai">华东地区（上海）</Select.Option>
                                        <Select.Option value="ap-singapore">亚太东南（新加坡）</Select.Option>
                                        <Select.Option value="ap-tokyo">亚太东北（东京）</Select.Option>
                                        <Select.Option value="eu-frankfurt">欧洲地区（法兰克福）</Select.Option>
                                        <Select.Option value="na-ashburn">美国东部（弗吉尼亚）</Select.Option>
                                        <Select.Option value="na-siliconvalley">美国西部（硅谷）</Select.Option>
                                        <Select.Option value="sa-saopaulo">南美地区（圣保罗）</Select.Option>
                                    </Select>
                                </Form.Item>
                                <Form.Item label="轻量应用服务器">
                                    <Space>
                                        <Checkbox checked={(innerInfo as TenCloudSourceInfo).enableLightHouse} onChange={e => {
                                            e.stopPropagation();
                                            setInnerInfo({
                                                ...innerInfo,
                                                enableLightHouse: e.target.checked,
                                            });
                                        }} />
                                        <Popover trigger="hover" placement="right" title="提示" content="需要赋予QcloudLighthouseReadOnlyAccess权限">
                                            <InfoCircleOutlined />
                                        </Popover>
                                    </Space>
                                </Form.Item>
                                <Form.Item label="云解析">
                                    <Space>
                                        <Checkbox checked={(innerInfo as TenCloudSourceInfo).enableDns} onChange={e => {
                                            e.stopPropagation();
                                            setInnerInfo({
                                                ...innerInfo,
                                                enableDns: e.target.checked,
                                            });
                                        }} />
                                        <Popover trigger="hover" placement="right" title="提示" content="需要赋予QcloudDNSPodReadOnlyAccess权限">
                                            <InfoCircleOutlined />
                                        </Popover>
                                    </Space>
                                </Form.Item>
                                <Form.Item label="CDN">
                                    <Space>
                                        <Checkbox checked={(innerInfo as TenCloudSourceInfo).enableCdn} onChange={e => {
                                            e.stopPropagation();
                                            setInnerInfo({
                                                ...innerInfo,
                                                enableCdn: e.target.checked,
                                            });
                                        }} />
                                        <Popover trigger="hover" placement="right" title="提示" content="需要赋予QcloudCDNReadOnlyAccess权限">
                                            <InfoCircleOutlined />
                                        </Popover>
                                    </Space>
                                </Form.Item>
                            </>
                        )}
                    </>
                )}
            </Form>
        </Modal>
    );
};

export default EditLocalSourceModal;